---状态，该状态为复合状态，多个状态数据的合集
---@class State
---@field dataTable table<string,boolean>   状态数据键值对
---@field onChangeCallFunc function         状态变化回调
State = class()

function State:ctor()
    self.dataTable = {}
end

---设置状态中某键值数据
---@param key string
---@param value boolean
function State:Set(key, value)
    if self.dataTable[key] == nil or self.dataTable[key] ~= value then
        self.dataTable[key] = value;
        if self.onChangeCallFunc ~= nil then
            Debug.Log("state值被改了--"..key..":"..tostring(value));
            self.onChangeCallFunc();
        end
    end
end

---将传入的状态键值数据来设置本地键值数据
---@param otherState State
function State:SetByOther(otherState)
    if otherState == nil then
        return;
    end
    local haveChange = false;
    for k, v in pairs(otherState.dataTable) do
        if self.dataTable[k] == nil or self.dataTable[k] ~= v then
            self.dataTable[k] = v;
            if self.onChangeCallFunc ~= nil then
                Debug.Log("state值被改了--"..k..":"..tostring(v));
            end
            haveChange = true;
        end
    end
    if haveChange then
        if self.onChangeCallFunc ~= nil then
            self.onChangeCallFunc();
        end
    end
end

---获取状态中键值数据
---@param key string
---@return boolean
function State:Get(key)
    if self.dataTable[key] == nil then
        Debug.LogError("状态中没有包含该Key:"..key);
        return false;
    end
    return self.dataTable[key];
end

---设置状态变更回调
function State:SetStateChangeCallFunc(callFunc)
    self.onChangeCallFunc = callFunc;
end

---获取与目标状态中相同key值的数据
---@param otherState State
---@return State
function State:GetSameKeyData(otherState)
    local state = State.new();
    for k, v in pairs(self.dataTable) do
        if otherState:ContainKey(k) then
            state:Set(k,v);
        end
    end
    return state;
end

---是否包含目标键值
---@return boolean
function State:ContainKey(key)
    return self.dataTable[key] ~= nil;
end

---倒置状态数据
---@return State
function State:InversionValue()
    local state = State.new();
    for k, v in pairs(self.dataTable) do
        state:Set(k,not v);
    end
    return state;
end

---是否包含目标状态中所有的键值数据
---@param otherState State
---@return boolean
function State:ContainState(otherState)
    for k, v in pairs(otherState.dataTable) do
        if (not self:ContainKey(k)) or self:Get(k) ~= v then
            return false;
        end
    end
    return true;
end
---获取与目标状态键值中不同值部分的键列表
---@param otherState State
---@return string[]
function State:GetValueDifferences(otherState)
    local keys = {}
    local index = 1;
    for k, v in pairs(otherState.dataTable) do
        if (not self:ContainKey(k)) or self:Get(k) ~= v then
            keys[index] = k;
            index = index + 1;
        end
    end
    return keys;
end

---获取与目标状态键值中我方不存在的键列表
---@param otherState State
---@return string[]
function State:GetNotExistKeys(otherState)
    local keys = {}
    local index = 1;
    for k, v in pairs(otherState.dataTable) do
        if not self:ContainKey(k) then
            keys[index] = k;
            index = index + 1;
        end
    end
    return keys;
end

---从其他状态中拷贝键值数据
---@param otherState State
function State:Copy(otherState)
    self:Clear();
    self:SetByOther(otherState);
end

---清理状态键值数据
function State:Clear()
    self.dataTable = {}
end

---@return string
function State:ToString()
    local str = "";
    for k, v in pairs(self.dataTable) do
        str = str.."key:"..k.."     value:"..tostring(v).."\r\n";
    end
    return str;
end